/**
 * 郭楠project
 * com.gn.commons
 * AbstractBaseEntityDao.java
 * 创建人:TonyGuo 
 * 时间：2016年12月11日-下午8:06:33 
 * 2016Tm公司-版权所有
 */
package com.gn.commons;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;

import org.apache.commons.lang.reflect.FieldUtils;
import org.springframework.beans.factory.InitializingBean;

import com.taoxeo.commons.core.dao.BaseEntityDao;
import com.taoxeo.commons.core.dao.exception.NullIdException;
import com.taoxeo.commons.lang.IdUtils;

/**
 * The Class AbstractBaseEntityDao.
 *
 * @param <T> the generic type
 * @param <ID> the generic type
 * @author Derek
 * @version 1.0, 2014-2-7
 */
public abstract class AbstractBaseEntityDao<T, ID extends Serializable> implements BaseEntityDao<T, ID>, InitializingBean {
	/** The entity class. */
	protected Class<T> entityClass;
	
	/** The id field. */
	protected Field idField = null;
	
	/**
	 * Instantiates a new abstract base entity dao.
	 */
	public AbstractBaseEntityDao(){
		// 获取泛型类型
		entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
	/**
	 * 初始化方法
	 * 
	 * 1. 实现类初始化 idField
	 */
	protected abstract void init();
	
	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		init();
	}

	/**
	 * 主键ID生成器.
	 *
	 * @return the ID
	 */
	protected ID generateId() {
		if (idField.getType() == String.class) {
			return (ID) IdUtils.uuid();
		}
		else {
			throw new NullIdException("ID Generator Not Support this type:" + idField.getType()
					+ ".  Please Override generateId() method for manual generte!");
		}
	}
	
	/**
	 * Gets the id.
	 *
	 * @param entity the entity
	 * @return the id
	 */
	protected ID getId(T entity) {
		if (idField != null) {
			try {
				ID value = (ID) FieldUtils.readField(idField, entity, true);
				return value;
			}
			catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Sets the id.
	 *
	 * @param entity the entity
	 * @param id the id
	 */
	protected void setId(T entity, ID id) {
		if (idField != null) {
			try {
				FieldUtils.writeField(idField, entity, id, true);
			}
			catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
	}
}